using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

using PMServiceDesk.DataType;
using PMServiceDesk.Utils.ManejoDatos;

namespace PMServiceDesk.DataAccess
{
    public class LineaBaseDetalleData
    {
        #region Variables

        private string _select;
        private string _join;
        private string _where;
        private int _totalRegistros = 0;

        private Dictionary<string, object> _parametrosConsulta;

        #endregion

        #region Propiedades

        protected string Where
        {
            get
            {
                if (_where == "") return "";

                return "WHERE " + _where.Substring(3);
            }
        }

        #endregion

        #region Constructores

        public LineaBaseDetalleData()
        {
            this._limpiarConsulta();
        }

        #endregion

        #region Metodos

        private void _limpiarConsulta()
        {
            _select = "";
            _join = "";
            _where = "";
            _parametrosConsulta = new Dictionary<string, object>();
        }

        private DataUtil _consultaDataReader(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            DataUtil data = null;

            if(paginaActual==0)
                data = new DataUtil(TypeDataBase.PMServiceDesk, CommandType.Text, _select + _join + this.Where + orderBy,_parametrosConsulta);
            else
                data = DataReader.ReturnPagingReader(TypeDataBase.PMServiceDesk, _select, _join, this.Where, this._parametrosConsulta, paginaActual, cantidadMostrar, orderBy, ref _totalRegistros);

            this._limpiarConsulta();

            return data;
        }

        public void Grabar(LineaBaseDetalleType lineaBaseDetalle)
        {
            using (DataUtil d = this._grabar())
            {
                d.AddParameter("@ID", (lineaBaseDetalle.Id == null ? "0" : lineaBaseDetalle.Id));
                d.AddParameter("@LINEABASEID", lineaBaseDetalle.LineaBaseId);
                d.AddParameter("@PAQUETETRABAJOID", lineaBaseDetalle.PaqueteTrabajoId);
                d.AddParameter("@USUARIORESPONSABLEID", lineaBaseDetalle.UsuarioResponsableId);
                d.AddParameter("@CODIGOCUENTA", lineaBaseDetalle.CodigoCuenta);
                d.AddParameter("@NOMBRE", lineaBaseDetalle.Nombre);
                d.AddParameter("@FECHAINICIOPROYECTADO", lineaBaseDetalle.FechaInicioProyectado);
                d.AddParameter("@FECHAFINPROYECTADO", lineaBaseDetalle.FechaFinProyectado);

                lineaBaseDetalle.Id = d.ExecuteScalar(true).ToString();
            }
        }

        public LineaBaseDetalleType Cargar()
        {
            List<LineaBaseDetalleType> l = this.CargarLista();

            if (l.Count == 0) return null;

            return l[0];
        }

        public List<LineaBaseDetalleType> CargarLista()
        {
            List<LineaBaseDetalleType> l = new List<LineaBaseDetalleType>();

            using (DataUtil d = this._consultaCargar())
                using (IDataReader r = d.ExecuteReader())
                {
                    LineaBaseDetalleType o = null;

                    while (r.Read())
                    {
                        o = new LineaBaseDetalleType();

                        o.Id = r.GetValue(d.GetOrdinalReader("ID")).ToString();
                        o.LineaBaseId = r.GetValue(d.GetOrdinalReader("LINEABASEID")).ToString();
                        o.PaqueteTrabajoId = r.GetValue(d.GetOrdinalReader("PAQUETETRABAJOID")).ToString();
                        o.UsuarioResponsableId = r.GetValue(d.GetOrdinalReader("USUARIORESPONSABLEID")).ToString();
                        o.CodigoCuenta = r.GetValue(d.GetOrdinalReader("CODIGOCUENTA")).ToString();
                        o.Nombre = r.GetValue(d.GetOrdinalReader("NOMBRE")).ToString();
                        o.FechaInicioProyectado = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAINICIOPROYECTADO")));
                        o.FechaFinProyectado = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAFINPROYECTADO")));

                        l.Add(o);
                    }
                }

            return l;
        }

        public List<LineaBaseDetalleType> CargarListaVista(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            List<LineaBaseDetalleType> l = new List<LineaBaseDetalleType>();

            using (DataUtil d = this._consultaCargarVista(paginaActual, cantidadMostrar,orderBy))
                using (IDataReader r = d.ExecuteReader())
                {
                    LineaBaseDetalleType o = null;

                    while (r.Read())
                    {
                        o = new LineaBaseDetalleType();

                        o.Id = r.GetValue(d.GetOrdinalReader("ID")).ToString();
                        o.LineaBaseId = r.GetValue(d.GetOrdinalReader("LINEABASEID")).ToString();
                        o.PaqueteTrabajoId = r.GetValue(d.GetOrdinalReader("PAQUETETRABAJOID")).ToString();
                        o.UsuarioResponsableId = r.GetValue(d.GetOrdinalReader("USUARIORESPONSABLEID")).ToString();
                        o.CodigoCuenta = r.GetValue(d.GetOrdinalReader("CODIGOCUENTA")).ToString();
                        o.Nombre = r.GetValue(d.GetOrdinalReader("NOMBRE")).ToString();
                        o.FechaInicioProyectado = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAINICIOPROYECTADO")));
                        o.FechaFinProyectado = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAFINPROYECTADO")));

                        l.Add(o);
                    }
                }

            if (l.Count < _totalRegistros) l.Capacity = _totalRegistros;

            return l;
        }

        public List<LineaBaseDetalleType> CargarGestionLineaBase(string proyectoId,string lineaBaseId,DateTime fechaValor)
        {
            _parametrosConsulta.Add("@PROYECTOID", proyectoId);
            _parametrosConsulta.Add("@LINEABASEID", lineaBaseId);
            _parametrosConsulta.Add("@FECHAVALOR", fechaValor);

            List<LineaBaseDetalleType> l = new List<LineaBaseDetalleType>();

            using (DataUtil d = this._consultaCargarGestionLineaBase())
                using (IDataReader r = d.ExecuteReader())
                {
                    LineaBaseDetalleType o = null;

                    while (r.Read())
                    {
                        o = new LineaBaseDetalleType();

                        o.Id = r.GetValue(d.GetOrdinalReader("ID")).ToString();
                        o.PaqueteTrabajoId = r.GetValue(d.GetOrdinalReader("PAQUETETRABAJOID")).ToString();
                        o.CodigoCuenta = r.GetValue(d.GetOrdinalReader("CODIGOCUENTA")).ToString();
                        o.Nombre = r.GetValue(d.GetOrdinalReader("NOMBRE")).ToString();
                        o.TipoPaqueteTrabajo = r.GetValue(d.GetOrdinalReader("TIPOPAQUETETRABAJO")).ToString();
                        o.UsuarioResponsable = r.GetValue(d.GetOrdinalReader("USUARIORESPONSABLE")).ToString();
                        o.PorcentajeAvance = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("PORCENTAJEAVANCE")));
                        o.FechaInicioProyectado = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAINICIOPROYECTADO")));
                        o.FechaFinProyectado = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAFINPROYECTADO")));
                        o.FechaInicioReal = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAINICIOREAL")));
                        o.FechaFinReal = ConvertFormat.Char_To_Date(r.GetValue(d.GetOrdinalReader("FECHAFINREAL")));
                        o.BAC = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("BAC")));
                        o.PV = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("PV")));
                        o.PV_SPI = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("PV_SPI")));
                        o.EV = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("EV")));
                        o.AC = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("AC")));
                        o.CPI = SoporteData.CalcularCPI(o.EV, o.AC);
                        o.SPI = SoporteData.CalcularSPI(o.EV, o.PV_SPI);

                        l.Add(o);
                    }
                }

            return (
                        from registro in l
                        orderby registro.CodigoCuenta
                        select registro
                   ).ToList();
        }

        #endregion

        #region SQL

        private DataUtil _grabar()
        {
            string sql = @"IF(NOT EXISTS(SELECT 1 FROM LINEABASEDETALLE WHERE ID=@ID)) 
                           BEGIN
                               INSERT INTO LINEABASEDETALLE
                               (
                                   LINEABASEID
                                  ,PAQUETETRABAJOID
                                  ,USUARIORESPONSABLEID
                                  ,CODIGOCUENTA
                                  ,NOMBRE
                                  ,FECHAINICIOPROYECTADO
                                  ,FECHAFINPROYECTADO
                               )
                               VALUES
                               (
                                   @LINEABASEID
                                  ,@PAQUETETRABAJOID
                                  ,@USUARIORESPONSABLEID
                                  ,@CODIGOCUENTA
                                  ,@NOMBRE
                                  ,@FECHAINICIOPROYECTADO
                                  ,@FECHAFINPROYECTADO
                               )

                               SELECT @@IDENTITY
                           END
                           ELSE
                           BEGIN
                               UPDATE LINEABASEDETALLE SET
                               LINEABASEID=@LINEABASEID
                              ,PAQUETETRABAJOID=@PAQUETETRABAJOID
                              ,USUARIORESPONSABLEID=@USUARIORESPONSABLEID
                              ,CODIGOCUENTA=@CODIGOCUENTA
                              ,NOMBRE=@NOMBRE
                              ,FECHAINICIOPROYECTADO=@FECHAINICIOPROYECTADO
                              ,FECHAFINPROYECTADO=@FECHAFINPROYECTADO
                               WHERE ID=@ID

                               SELECT @ID
                           END";

            return new DataUtil(TypeDataBase.PMServiceDesk, CommandType.Text, sql);
        }

        private DataUtil _consultaCargar()
        {
            _select = @"SELECT
                        LI.ID
                       ,LI.LINEABASEID
                       ,LI.PAQUETETRABAJOID
                       ,LI.USUARIORESPONSABLEID
                       ,LI.CODIGOCUENTA
                       ,LI.NOMBRE
                       ,LI.FECHAINICIOPROYECTADO
                       ,LI.FECHAFINPROYECTADO
                        ";

            _join = @"FROM DBO.LINEABASEDETALLE [LI] 
                      ";

            return this._consultaDataReader();
        }

        private DataUtil _consultaCargarGestionLineaBase()
        {
            string sql = @"SELECT
                            LD.ID															[ID]
                            ,NULL															[PAQUETETRABAJOID]
                            ,LD.CODIGOCUENTA												[CODIGOCUENTA]
                            ,LD.NOMBRE														[NOMBRE]
                            ,NULL															[TIPOPAQUETETRABAJO]
                            ,NULL															[USUARIORESPONSABLE]
                            ,0																[PORCENTAJEAVANCE]
                            ,'01/01/1900'								                    [FECHAINICIOPROYECTADO]
                            ,'01/01/1900'								                    [FECHAFINPROYECTADO]
                            ,'01/01/1900'								                    [FECHAINICIOREAL]
                            ,'01/01/1900'								                    [FECHAFINREAL]
                            ,0									                            [BAC]
                            ,0									                            [PV]
                            ,0									                            [PV_SPI]
                            ,0									                            [EV]
                            ,0									                            [AC]
                            FROM LINEABASEDETALLE [LD] 
                            WHERE LD.LINEABASEID = @LINEABASEID
                            AND LD.PAQUETETRABAJOID IS NULL

                            UNION ALL
    
                            SELECT 
                            LD.ID																					[ID]
                            ,LD.PAQUETETRABAJOID																	[PAQUETETRABAJOID]
                            ,LD.CODIGOCUENTA																		[CODIGOCUENTA]
                            ,LD.NOMBRE																				[NOMBRE]
                            ,TIPPAQ.NOMBRE																			[TIPOPAQUETETRABAJO]
                            ,RECRESP.NOMBRE																			[USUARIORESPONSABLE]
                            ,PAQ.PORCENTAJEAVANCE																	[PORCENTAJEAVANCE]
                            ,CONVERT(VARCHAR(10),LD.FECHAINICIOPROYECTADO,103)										[FECHAINICIOPROYECTADO]
                            ,CONVERT(VARCHAR(10),LD.FECHAFINPROYECTADO,103)											[FECHAFINPROYECTADO]
                            ,CONVERT(VARCHAR(10),ISNULL(PAQ.FECHAINICIOREAL,PAQ.FECHAINICIOPROYECTADO),103)			[FECHAINICIOREAL]
                            ,CONVERT(VARCHAR(10),ISNULL(PAQ.FECHAFINREAL,PAQ.FECHAFINPROYECTADO),103)				[FECHAFINREAL]
                            ,SUM
                            (
                                DBO.FN_CALCULAR_BAC
                                (
                                    REC.TIPOCOSTOID
                                   ,REC.COSTO
                                   ,RECLD.PORCENTAJEUSO
                                   ,RECLD.CANTIDAD
                                   ,REC.CALENDARIOID
                                   ,LD.FECHAINICIOPROYECTADO
                                   ,LD.FECHAFINPROYECTADO
                                )
                            )																						[BAC]
                            ,SUM
                            (
                                DBO.FN_CALCULAR_PV
                                (
                                    REC.TIPOCOSTOID
                                   ,REC.COSTO
                                   ,RECLD.PORCENTAJEUSO
                                   ,RECLD.CANTIDAD
                                   ,REC.CALENDARIOID
                                   ,LD.FECHAINICIOPROYECTADO
                                   ,LD.FECHAFINPROYECTADO
                                   ,@FECHAVALOR
                                )
                            )																						[PV]
                            ,SUM
                            (
                                DBO.FN_CALCULAR_PV_SPI
                                (
                                    REC.TIPOCOSTOID
                                   ,REC.COSTO
                                   ,RECLD.PORCENTAJEUSO
                                   ,RECLD.CANTIDAD
                                   ,REC.CALENDARIOID
                                   ,LD.FECHAINICIOPROYECTADO
                                   ,LD.FECHAFINPROYECTADO
                                   ,PAQ.FECHAFINREAL
                                   ,@FECHAVALOR
                                )
                            )																						[PV_SPI]    
                            ,SUM
                            (
                                DBO.FN_CALCULAR_EV
                                (
                                    REC.TIPOCOSTOID
                                   ,REC.COSTO
                                   ,RECLD.PORCENTAJEUSO
                                   ,RECLD.CANTIDAD
                                   ,REC.CALENDARIOID
                                   ,LD.FECHAINICIOPROYECTADO
                                   ,LD.FECHAFINPROYECTADO
                                   ,PAQ.PORCENTAJEAVANCE
                                   ,@FECHAVALOR
                                )
                            )																							[EV]    
                            ,ISNULL(PAQCALC.AC,0)																		[AC]
                            FROM LINEABASEDETALLE [LD] 
                            INNER JOIN PAQUETETRABAJO [PAQ] ON PAQ.ID = LD.PAQUETETRABAJOID
                            INNER JOIN TIPOPAQUETETRABAJO [TIPPAQ] ON TIPPAQ.ID = PAQ.TIPOPAQUETETRABAJOID
                            INNER JOIN USUARIORECURSO [RESP] ON RESP.USUARIOID = PAQ.USUARIORESPONSABLEID
                            INNER JOIN RECURSO [RECRESP] ON RECRESP.ID = RESP.RECURSOID AND RECRESP.PROYECTOID = PAQ.PROYECTOID
                            INNER JOIN RECURSOLINEABASEDETALLE [RECLD] ON RECLD.LINEABASEDETALLEID = LD.ID
                            INNER JOIN RECURSO [REC] ON REC.ID = RECLD.RECURSOID
                            LEFT JOIN  
                            (
                                SELECT 
                                PAQTRA.ID																				[PAQUETETRABAJOID]
                                ,SUM
                                (
                                    DBO.FN_CALCULAR_AC
                                    (
                                        REC.TIPOCOSTOID
                                       ,REC.COSTO
                                       ,RECACT.PORCENTAJEUSO
                                       ,RECACT.CANTIDAD
                                       ,REC.CALENDARIOID
                                       ,ACT.FECHAINICIO
                                       ,ACT.FECHAFIN
                                       ,@FECHAVALOR
                                    )
                                )																						[AC]
                                FROM PAQUETETRABAJO [PAQTRA] 
                                INNER JOIN ACTIVIDAD [ACT] ON ACT.PAQUETETRABAJOID = PAQTRA.ID
                                INNER JOIN RECURSOACTIVIDAD [RECACT] ON RECACT.ACTIVIDADID = ACT.ID
                                INNER JOIN RECURSO [REC] ON REC.ID = RECACT.ID
                                WHERE PAQTRA.PROYECTOID = @PROYECTOID
                                GROUP BY PAQTRA.ID
                           ) [PAQCALC] ON PAQCALC.PAQUETETRABAJOID = LD.PAQUETETRABAJOID
                            WHERE LD.LINEABASEID = @LINEABASEID
                            GROUP BY
                            LD.ID	
                            ,LD.PAQUETETRABAJOID
                            ,LD.CODIGOCUENTA
                            ,LD.NOMBRE	
                            ,TIPPAQ.NOMBRE	
                            ,RECRESP.NOMBRE	
                            ,PAQ.PORCENTAJEAVANCE	
                            ,LD.FECHAINICIOPROYECTADO
                            ,LD.FECHAFINPROYECTADO	
                            ,ISNULL(PAQ.FECHAINICIOREAL,PAQ.FECHAINICIOPROYECTADO)
                            ,ISNULL(PAQ.FECHAFINREAL,PAQ.FECHAFINPROYECTADO)
                            ,PAQCALC.AC    ";

            DataUtil d = new DataUtil(TypeDataBase.PMServiceDesk, CommandType.Text, sql, _parametrosConsulta);

            this._limpiarConsulta();

            return d;
        }

        private DataUtil _consultaCargarVista(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            _select = @"SELECT
                        LI.ID
                       ,LI.LINEABASEID
                       ,LI.PAQUETETRABAJOID
                       ,LI.USUARIORESPONSABLEID
                       ,LI.CODIGOCUENTA
                       ,LI.NOMBRE
                       ,LI.FECHAINICIOPROYECTADO
                       ,LI.FECHAFINPROYECTADO
                        ";

            _join = @"FROM DBO.LINEABASEDETALLE [LI] 
                      ";

            return this._consultaDataReader(paginaActual, cantidadMostrar, orderBy);
        }

        public void FiltrarPorId(string id)
        {
            _where += @"AND LI.ID=@ID
                                 ";

            _parametrosConsulta.Add("@ID", id);
        }

        #endregion
    }
}
